<?php
namespace PsiFramework\Classes\Util\HTTP;

use \PsiFramework\Classes\Util\Log\Logger;
use \PsiFramework\Classes\Util\HTTP\Request;

/**
 * PsiFramework
 * Php Simple Framework
 *
 * @author Rémi San
 * @version beta
 */

/**
 * The Session class allows to manage a session
 *
 * @package Util.HTTP
 */
class Session
{

    protected /*array*/ $_session ;
    protected /*array*/ $_cookies ;

    private /*string*/ $_sessionCookiesName;
    
    protected static $_singleton = null ;

    /**
     * Session constructor
     */
    protected function __construct()
    {
        $sessionId = Request::getInstance()->getParameter('sessionid');
        $this->start($sessionId);
    }

    /**
     * start the session
     */
    private function start(/*string*/ $sessionId=null)
    {
    	if (!isNullOrEmptyString($sessionId)) {
    	    @session_id($sessionId);
    	}
        @session_start();
        $this->_session = &$_SESSION ;
        
        $this->_cookies = &$_COOKIE;
        
        $logger = new Logger('Session');
        $logger->debug('session id : ' . $this->getId());
        
        $sessionCookies = $this->get($this->_sessionCookiesName);
        if (!is_null($sessionCookies) && count($sessionCookies)>0) {
            foreach ($sessionCookies as $sessionCookie) {
                $logger->debug('Setting cookie ['.$sessionCookie['name'].'] : '.$sessionCookie['value']);
                $this->setCookie($sessionCookie['name'], $sessionCookie['value'], $sessionCookie['expire']);
            }
        }
    }

    /**
     * This function allows to retrieve a parameter by specifying its name
     *
     * @param     string    $paramName    the name of the requested parameter
     * @return     mixed    the parameter
     */
    public function get(/*string*/ $paramName)
    {
        $return = null ;
        if (isset($this->_session[$paramName])) {
            $return = $this->_session[$paramName] ;
        }
        return $return;
    }
    
    public function getCookie(/*string*/ $paramName)
    {
    	$return = null ;
    	if (isset($this->_cookies[$paramName])) {
    		$return = $this->_cookies[$paramName] ;
    	} else {
    	    $sessionCookies = $this->get($this->_sessionCookiesName);
    	    if (!is_null($sessionCookies) && count($sessionCookies)>0) {
    	        if (isset($sessionCookies[$paramName])) {
    	        	$return = $sessionCookies[$paramName] ;
    	        }
    	    }
    	}
    	return $return;
    }

    /**
     * This function allows to add a parameter to the session
     *
     * @param  string  $paramName the name of the parameter to store
     * @param  mixed   $object    the object parameter to store in the session
     * @return boolean did it work ?
     */
    public function set(/*string*/ $paramName, /*mixed*/ $object)
    {
        $return = false ;
        if ($this->_session[$paramName] = $object) {
            $return = true ;
        }
        return($return);
    }

    public function setCookie(/*string*/ $paramName, /*string*/ $string, /*int*/ $expire)
    {
        return setcookie($paramName, $string, $expire);
    }
    
    public function setDelayedCookie(/*string*/ $paramName, /*string*/ $string, /*int*/ $expire)
    {
    	$cookieParams = array('name'=>$paramName, 'value'=>$string, 'expire'=>$expire);
    	$sessionCookies = $this->get($this->_sessionCookiesName);
    	if (!is_null($sessionCookies)) {
    	    $sessionCookies = array();
    	}
    	$sessionCookies[$paramName] = $cookieParams;
    	$this->set($this->_sessionCookiesName, $sessionCookies);
    }
    
    /**
     * The function returns the session id
     *
     * @return    string    the session id
     */
    public function getId()
    {
        return session_id();
    }

    /**
     * This function allows to reset the session
     */
    public function reset()
    {
    	$this->close();
    	$this->start();
    }
    
    /**
     * This function allows to close the session
     */
    public function close()
    {
        @session_unset();
        @session_destroy();
        @session_write_close();
        @setcookie(session_name(), '', 0, '/');
        @session_regenerate_id(true);
    }

    /**
     * Interrupts the current session
     * 
     * @return void
     */
    public function interrupt()
    {
        session_write_close();
    }
    
    /**
     * Function to be called instead of the constructor.
     * It starts the session.
     *
     * @return Session instance
     */
    public static function getInstance()
    {

        if (self::$_singleton==null) {
            self::$_singleton = new Session();
        }

        return self::$_singleton;
    }

}
